import http from '@ohos.net.http';
import { RequestOptions } from './RequestOptions';
import { hilog } from '@kit.PerformanceAnalysisKit';

/**
 * Http请求器
 */
export class HttpCore {

  /**
   * 发送请求
   * @param requestOption
   * @returns Promise
   */
  request<T>(requestOption: RequestOptions): Promise<T> {
    return new Promise<T>((resolve, reject) => {
      this.sendRequest(requestOption)
        .then((response) => {
          if (typeof response.result !== 'string') {
            reject(new Error('Invalid data type'));

          } else {
            let bean: T = JSON.parse(response.result);
            if (bean) {
              resolve(bean);
            } else {
              reject(new Error('Invalid data type,JSON to T failed'));
            }

          }
        })
        .catch((error) => {
          reject(error);
        });
    });
  }


  private sendRequest(requestOption: RequestOptions): Promise<http.HttpResponse> {

    // 每一个httpRequest对应一个HTTP请求任务，不可复用
    let httpRequest = http.createHttp();

    let resolveFunction, rejectFunction;
    const resultPromise = new Promise<http.HttpResponse>((resolve, reject) => {
      resolveFunction = resolve;
      rejectFunction = reject;
    });

    if (!this.isValidUrl(requestOption.url)) {
      return Promise.reject(new Error('url格式不合法.'));
    }
    let finalUrl = this.appendQueryParams(requestOption.url, requestOption.queryParams);
    hilog.error(0x0000, 'testTag', 'finalUrl:'+finalUrl);
    let promise = httpRequest.request(finalUrl, {
      method: requestOption.method,
      header: requestOption.header,
      extraData: requestOption.extraData, // 当使用POST请求时此字段用于传递内容
      expectDataType: http.HttpDataType.STRING // 可选，指定返回数据的类型
    });

    promise.then((response) => {
      hilog.error(0x0000, 'testTag', 'response:'+response);
      console.info('Result:' + response.result);
      console.info('code:' + response.responseCode);
      console.info('header:' + JSON.stringify(response.header));


      if (http.ResponseCode.OK !== response.responseCode) {
        throw new Error('http responseCode !=200');
      }
      resolveFunction(response);

    }).catch((err) => {
      rejectFunction(err);
    }).finally(() => {
      // 当该请求使用完毕时，调用destroy方法主动销毁。
      httpRequest.destroy();
    })
    return resultPromise;
  }


  private appendQueryParams(url: string, queryParams: Record<string, string>): string {
    // 检查URL中是否已经存在查询参数
    let separator = url.indexOf("?") > 0 ? "&" : "?";
    // 将queryParams转换为查询字符串
    let queryString = Object.entries(queryParams)
      .map(([key, value]) => `${encodeURIComponent(key)}=${encodeURIComponent(value)}`)
      .join("&");
    // 将查询字符串拼接到URL上
    return url + separator + queryString;;
  }

  private isValidUrl(url: string): boolean {
    // 定义URL的正则表达式
    const urlPattern: string =
      '^((https?|ftp)://)' + // 匹配协议 http, https, ftp
        '?([\\w-]+\\.)+[a-z]{2,6}' + // 匹配域名
        '(?:\\d+)?' + // 匹配端口号 (可选)
        '(\\/[\\w.-]*)*\\/?' + // 匹配路径
        '(\\?[^#]*)?' + // 匹配查询字符串 (可选)
        '(#.*)?$'; // 匹配锚点 (可选)

    const regex = new RegExp(urlPattern, 'i'); // 'i' 表示不区分大小写
    let ret = regex.test(url);
    hilog.error(0x0000, 'testTag', 'isValidUrl:'+ret);
    return ret;
    // return true;
  }
}

export const httpCore = new HttpCore();